﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using frag_boardgame;
using GameService;
using System.Collections.Generic;

namespace Website
{
    public partial class game : Page
    {
       
        protected Game g;
        protected void Page_Load(object sender, EventArgs e)
        {
            Initilize();
        }
        protected void Initilize()
        {

            Board1.Cols = Master.GetCurrentRoom().Info.config.Cols;
            Board1.Rows = Master.GetCurrentRoom().Info.config.Rows;
            Board1.OnSquareSelect += new Board.squareSelect(Board1_OnSquareSelect);
            
            g = Master.GetCurrentRoom().Game;
            StartGame();
            UpdateBoard();
            UpdateLables();
            Timer1.Enabled = true;

            if (g.Data.CurrentPlayer.Name == Master.GetUserInfo().config.Name)
                MyTurn();

            var userDataSource = from user in Master.GetCurrentRoom().Users.Values
                                 select new
                                 {
                                     Name = user.config.Name,
                                     Uid = user.Uid
                                 };
            UserRepeater.DataSource = userDataSource;
            UserRepeater.DataBind();
            Messages.SelectedIndex = Messages.Items.Count - 1;

        }

        void Board1_OnSquareSelect(Square sqr)
        {
            if (IsMyTurn())
            {
                if (sqr.player != null)
                {
                    ShootButton1_OnTryShoot(sqr.player.ID);
                }
                else
                {
                    MoveToSqr(sqr);
                }
                
            }
            UpdateValues(true);
            UpdateAllPanels();
        }

      
        
        protected void StartGame()
        {
            Room room = Master.GetCurrentRoom();
            if (!room.IsPlaying)
            {
                Master.GetCurrentRoom().IsPlaying = true;

                
                for (int i = 0; i < (room.Info.config.NumberOfPlayers - room.Info.nPlayers); i++) //Fill room with AI players
                {
                    PlayerConfiguration AIConfiguraion = new PlayerConfiguration();
                    AIConfiguraion.StartingPosition = null;
                    AIConfiguraion.SetStats(3, 2, 2);
                    AIConfiguraion.Control = Player.Controller.AI;
                    AIConfiguraion.Name = "AI " + (i + 1);
                    room.Info.config.addPlayer(AIConfiguraion);
                }
                g.New(Master.GetCurrentRoom().Info.config);
                g.IsCommunication = true;
                g.StartGame();
               
            }
        }
        protected void UpdateBoard()
        {
            //Board1.GameBoard = g.Data.Board;
            Board1.DrawBoard(g.Data.Board);
        }


        protected bool IsMyTurn()
        {
            return g.Data.CurrentPlayer.Name == Master.GetUserInfo().config.Name;
        }

        protected void WriteMessage(string txt)
        {
            
            Messages.Items.Add(txt);
            Messages.SelectedIndex = Messages.Items.Count - 1;

        }

        protected void NotifyMessage(string msg)
        {
            WriteMessage(msg);
            foreach (UserInfo user in Master.GameManager.users.Values)
            {
                if (user != Master.GetUserInfo())
                    user.Update(msg);
            }
            
            
        }

        private void MoveToSqr(Square sqr)
        {

            int horiDist = sqr.Column - g.Data.CurrentPlayer.Column;
            int verDist = sqr.Row - g.Data.CurrentPlayer.Row;
            bool isMoved = false;
            
            if (horiDist != 0 && verDist == 0)
            {
                g.MovePlayerHorizontally(horiDist, true);
                isMoved = true;
            }
            else if (horiDist == 0 && verDist != 0)
            {
                g.MovePlayerVertically(verDist, true);
                isMoved = true;
            }
            if (isMoved)
                WriteMessage(string.Format("{0} has made a move!" ,Master.GetUserInfo().config.Name));
            btnUndo.Enabled = true;
        }




        protected void UnEnableItems()
        {
            btnRedo.Enabled = false;
            btnUndo.Enabled = false;
            FinishTurn.Enabled = false;
        }
        protected void EndTurn()
        {
            UnEnableItems();
            Timer1.Enabled = true;
            ToggleCurrentPlayer();
        }

        protected void UpdateLables()
        {
            lbCurrentPlayer.Text = g.Data.CurrentPlayer.Name;
            lblMovesLeft.Text = g.Data.CurrentPlayer.MovesLeft.ToString();
            lblShootsLeft.Text = g.Data.CurrentPlayer.ShotsLeft.ToString();
            lblHealth.Text = GetHealth();
            
            
        }
        protected string GetHealth()
        {
            string temp = "";
            foreach (Player player in g.Data.GetPlayersList())
            {
                temp += player.Name + ": <b>" + player.Health.ToString() + "</b> ";
            }
            return temp;
        }

        
        void ShootButton1_OnTryShoot(int playerID)
        {
            Player current_player = g.Data.CurrentPlayer;
            ShootingValues vals = g.Shoot(playerID);
            UpdateShoot(vals);
            if (current_player != g.Data.CurrentPlayer)
                EndTurn();
            else
                UpdateValues(true);
        }

        
        protected void UpdateShoot(ShootingValues vals)
        {
            ShootingOptionsEnum shootingRes = vals.Options;
            string shooter = vals.ShooterName;
            string target = vals.TargetName;
            string msg="";
            if (shootingRes == ShootingOptionsEnum.Hit)
            {
                
                msg = "Player " + shooter + " hit Player " + target;
                msg += "\nPlayer " + shooter + " Rolls: " + vals.ShooterDices;
                msg += "\nPlayer " + target + " Rolls: " + vals.TargetDices;
                msg += "\nDamage is: " + vals.ShooterDices / vals.TargetDices;


            }
            else if (shootingRes == ShootingOptionsEnum.Miss)
            {
                msg = "Player " + shooter + " missed Player " + target;
            }
            else if (shootingRes == ShootingOptionsEnum.CantShoot)
            {
                msg = "Player " + shooter + " can't shoot Player " + target;
            }
            else if (shootingRes == ShootingOptionsEnum.GameOver || shootingRes == ShootingOptionsEnum.PlayerKilled)
            {
                msg = "Player " + target + " was killed by " + shooter;
                if (shootingRes == ShootingOptionsEnum.GameOver)
                {
                    msg += "\nGame over! " + shooter + " Wins!!";
                    UpdateGameOver(msg);

                }
            }
            if (!(shootingRes == ShootingOptionsEnum.GameOver))
            {
                NotifyMessage(msg);
                
                
            }
        }

        protected void UpdateGameOver(string msg)
        {
            Master.WinGame();
            foreach (UserInfo user in Master.GameManager.users.Values)
            {
                if (user != Master.GetUserInfo())
                    user.GameOver(msg);
            }
            GameOver();
           

        }

        protected void ToggleCurrentPlayer()
        {
            if (IsMyTurn())
                MyTurn();
            else
            {

                if (g.Data.CurrentPlayer.Control == Player.Controller.Human)
                {
                    foreach (UserInfo user in Master.GameManager.users.Values)
                    {
                        if (user != Master.GetUserInfo())
                            user.ToggleCurrentPlayer();
                    }
                    UpdateAllPanels();
                }
                else
                {
                    String PlayerName = g.Data.CurrentPlayer.Name;
                    AI.PlayAI(g);
                    NotifyMessage(PlayerName + " has made a move");
                    UpdateValues(true);
                    ToggleCurrentPlayer();




                }
            }
            
        }

        protected void Messages_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        protected void Timer1_Tick(object sender, EventArgs e)
        {
            CheckMessages();
            
            
        }
        protected void UpdateGamePanels()
        {
            upnlBoard.Update();
            upnlLables.Update();
            upnlMessages.Update();
            

            
        }

        protected void UpdateAllPanels()
        {
            UpdateGamePanels();
            upnlFinish.Update();
            upnlUndoRedo.Update();
        }

        protected void MyTurn()
        {
            FinishTurn.Enabled = true;
            CheckMessages();
            Timer1.Enabled = false;
            UpdateAllPanels();

        }

        protected void CheckMessages()
        {
            List<UserInfo.Message> msgs;

            msgs = Master.GetUserInfo().GetMessages(true);


            if (msgs.Count > 0)
            {
                foreach (UserInfo.Message msg in msgs)
                {
                    if (msg.IsGameOver)
                        GameOver();
                    else if (msg.UpdateGameData)
                    {
                        WriteMessage(msg.Text);
                    }
                    else if (msg.ToggleCurrentPlayer)
                    {
                        if (IsMyTurn())
                        {
                            MyTurn();

                        }

                    }
                    UpdateValues(true);

                    if (IsMyTurn())
                        upnlUndoRedo.Update();

                }
            }
            
        }

        protected void UpdateValues()
        {
            UpdateBoard();
            UpdateLables();
        }

        protected void UpdateValues(bool GetHtml)
        {
            UpdateValues();
            if (GetHtml)
                UpdateGamePanels();
        }
        private void GameOver()
        {
            string winner = g.Data.GetPlayersList().ToArray()[0].Name;
            lblGameOver.Text = "Game Over! " + winner + " Wins!";
            lblGameOver.Visible = true;
            btnContinue.Visible = true;
            Panel3.Visible = true;
            UnEnableItems();
            UpdateAllPanels();
            UpnlGameOver.Update();
           
 
        }

        protected void btnUndo_Click(object sender, EventArgs e)
        {
            g.Undo();
            if (!g.CanUndo())
                btnUndo.Enabled = false;
            btnRedo.Enabled = true;
            NotifyMessage(Master.GetUserInfo().config.Name + " has undo move!");
            UpdateValues(true);
        }

        protected void btnRedo_Click(object sender, EventArgs e)
        {
            g.Redo();
            if (!g.CanRedo())
                btnRedo.Enabled = false;
            btnUndo.Enabled = true;
            NotifyMessage(Master.GetUserInfo().config.Name + " has redo move!");
            UpdateValues(true);
        }

        protected void FinishTurn_Click(object sender, EventArgs e)
        {
            g.FinishCurrentTurn();
            NotifyMessage(Master.GetUserInfo().config.Name + " Has finished turn");
            EndTurn();
            UpdateLables();
        }

        protected void btnContinue_Click(object sender, EventArgs e)
        {
            Master.GetCurrentRoom().IsPlaying = false;
            Master.LeaveRoom();
            
            Response.Redirect("gamelist.aspx");
        }

  
    }
}
